﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace Xenta.Utils
{
    /// <summary>
    /// Contains the language pack related helper methods.
    /// </summary>
    public static class LanguagePackHelper
    {
        /// <summary>
        /// Disassembles the language pack content into dictionary.
        /// </summary>
        /// <param name="content">The language pack content.</param>
        /// <returns>The dictionary.</returns>
        public static IDictionary<String, String> Disassemble(string content)
        {
            var xContent = XElement.Parse(content);
            var xSections = xContent.Element("sections");
            var dic = new Dictionary<String, String>();

            if(xSections != null && xSections.HasElements)
                foreach(var i in xSections.Elements("section"))
                    _Disassemble(dic, i, String.Empty);
            return dic;
        }
        private static void _Disassemble(IDictionary<String, String> dic,
            XElement xSection,
            string basePrefix)
        {
            string prefix = String.IsNullOrEmpty(basePrefix) ?
                xSection.Attribute("name").Value :
                String.Format("{0}.{1}", basePrefix, xSection.Attribute("name").Value);
            var xStrings = xSection.Element("strings");

            if(xStrings != null && xStrings.HasElements)
            {
                foreach(var i in xStrings.Elements("string"))
                {
                    string key = i.Attribute("key").Value;
                    if(String.IsNullOrWhiteSpace(key))
                        continue;
                    key = String.Format("{0}.{1}", prefix, key);
                    if(dic.ContainsKey(key))
                        continue;
                    dic.Add(key, i.Value);
                }
            }

            var xSections = xSection.Element("sections");
            if(xSections == null || !xSections.HasElements)
                return;

            foreach(var i in xSections.Elements("section"))
                _Disassemble(dic, i, prefix);
        }

        /// <summary>
        /// Assembles the language pack from dictionary.
        /// </summary>
        /// <param name="dic">The dictionary.</param>
        /// <returns>The language pack content.</returns>
        public static string Assemble(IDictionary<String, String> dic)
        {
            var content = new XElement("root", 
                new XElement("sections"));

            foreach(var kv in dic)
            {
                if(String.IsNullOrWhiteSpace(kv.Key))
                    continue;
                var parts = kv.Key.Split(new []
                {
                    '.'
                }, StringSplitOptions.RemoveEmptyEntries);
                if(parts.Length <= 1)
                    continue;

                var xSections = content.Element("sections");
                XElement xSection = null;

                for(int n = 0; n < parts.Length - 1; n++)
                {
                    xSection = xSections.Elements("section").SingleOrDefault(x => 
                        x.Attribute("name").Value.Equals(parts[n]));
                    if(xSection == null)
                    {
                        xSection = new XElement("section", 
                            new XAttribute("name", parts[n]), 
                            new XElement("sections"));
                        xSections.Add(xSection);
                    }
                    xSections = xSection.Element("sections");
                }

                var xStrings = xSection.Element("strings");
                if(xStrings == null)
                {
                    xStrings = new XElement("strings");
                    xSection.Add(xStrings);
                }
                xStrings.Add(new XElement("string", 
                    new XAttribute("key", parts.Last()), 
                    new XText(kv.Value)));
            }
            return content.ToString();
        }
    }
}
